package com.xiaomaoguai.fcp.pre.kepler.trace.interceptor;

import com.alibaba.fastjson.JSON;
import com.xiaomaoguai.fcp.pre.kepler.trace.constants.KeplerTraceConstant;
import com.xiaomaoguai.fcp.pre.kepler.router.buf.Buf;
import com.xiaomaoguai.fcp.pre.kepler.router.handler.handlercontext.TailContext;
import com.xiaomaoguai.fcp.pre.kepler.router.handler.handlers.TailHandler;
import io.opentracing.Span;
import io.opentracing.tag.Tags;
import org.aspectj.lang.ProceedingJoinPoint;

import java.util.Map;

/**
 * @author August.Zhang
 * @version v1.0.0
 * @date 2020/1/8 20:22
 * @since JDK 1.8
 */
public class TailHandlerAroundInterceptor extends AbstractHandlerInterceptor {

	@Override
	public boolean accept(ProceedingJoinPoint pjp) {
		Class<?> clazz = pjp.getTarget().getClass();
		return TailHandler.class.isAssignableFrom(clazz);
	}

	@Override
	public String getOperationName(final ProceedingJoinPoint pjp) {
		return pjp.getTarget().getClass().getSimpleName();
	}

	@Override
	public void invokeBeforeMethod(ProceedingJoinPoint pjp, Span span) {
		String handlerName = pjp.getTarget().getClass().getSimpleName();
		final Object[] args = pjp.getArgs();
		@SuppressWarnings("rawtypes") final TailContext tailContext = (TailContext) args[0];
		final Buf buf = tailContext.getBuf();
		final String productCode = (String) buf.get(KeplerTraceConstant.SPAN_TAG_PRODUCT_CODE);
		final String routerName = tailContext.getRouter().getRouterName();
		final Map<String, Object> context = tailContext.getBuf().getContext();
		final String beforeJson = JSON.toJSONString(context);

		Tags.COMPONENT.set(span, KeplerTraceConstant.TAG_COMPONENT_VALUE_TAIL);
		span.setTag(KeplerTraceConstant.SPAN_TAG_PRODUCT_CODE, productCode);
		span.setTag(KeplerTraceConstant.SPAN_TAG_ROUTER_NAME, routerName);
		span.setTag(KeplerTraceConstant.SPAN_TAG_HANDLER_NAME, handlerName);
		span.setTag(KeplerTraceConstant.SPAN_TAG_BEFORE_ROUTER_OUT, jaegerDataDesensitization.dataDesensitization(beforeJson));
	}

	@Override
	public void invokeAfterMethod(ProceedingJoinPoint pjp, Span span) {
		final Object[] args = pjp.getArgs();
		@SuppressWarnings("rawtypes") final TailContext tailContext = (TailContext) args[0];
		final Object context = tailContext.getOutParam();
		final String afterJson = JSON.toJSONString(context);
		span.setTag(KeplerTraceConstant.SPAN_TAG_AFTER_ROUTER_OUT, jaegerDataDesensitization.dataDesensitization(afterJson));
	}

}
